# 高阶函数：把函数作为参数传入，或者返回值是另外一个函数
# 函数式编程大量使用函数，减少了代码的重复，因此程序比较短，开发速度较快。

# 对任意两个数字，整理之后再求和
# 如下求两个数的绝对值之后 ，再求和
def sum_num(a, b):
    return abs(a) + abs(b)


print(sum_num(2, -3))  # 输出 5


# 一、函数的参数是函数

def sum_num2(a, b, f):
    """
    根据 函数 f整理之后求和
    :param a:
    :param b:
    :param f: 函数，根据这个函数整理
    :return:
    """
    return f(a) + f(b)


print(sum_num2(2, -3, abs))  # 输出：5 根据高阶函数 abs 求绝对值之后再 求和

# 把lambda表达式 作为函数传给 sum_num2,计算a,b两个参数的平方之后，再求和
print(sum_num2(2, -3, lambda n: n ** 2))  # 13  4+9=13

# 二、函数的返回值是函数
# 高阶函数除了可以接受函数作为参数外，还可以把函数作为结果值返回。
# 一个函数返回值（return）为另外一个函数。
# 注意：后面的闭包课程，还会讲到高阶函数
def sum_num3(*args):
    # print(type(args)) # 输出 <class 'tuple'>
    def sum_nums():
        sum = 0
        for arg in args:
            sum += arg
        return sum
    # 此处返回函数，函数名，不带()
    return sum_nums


print(sum_num3(1, 2, 3, 4)) # 返回函数 输出 <function sum_num3.<locals>.sum_nums at 0x000001FE839D1BC0>
print(sum_num3(1, 2, 3, 4)()) # 输出 10 后面加()才进行计算
print(sum_num3) # 输出 <function sum_num3 at 0x000001EFA30EA480>